package io.grpc.netty.shaded.io.grpc.netty;

import io.grpc.internal.ServerStream;
import io.grpc.netty.shaded.io.netty.channel.Channel;
import lombok.SneakyThrows;

import java.lang.invoke.MethodHandles;
import java.lang.invoke.VarHandle;

public class NettyChannelHelper {

    private final static VarHandle WRITE_QUEUE_HANDLE;
    private final static VarHandle CHANNEL_HANDLE;

    static {
        try {
            WRITE_QUEUE_HANDLE = MethodHandles.privateLookupIn(NettyServerStream.class, MethodHandles.lookup()).findVarHandle(NettyServerStream.class, "writeQueue", WriteQueue.class);
            CHANNEL_HANDLE = MethodHandles.privateLookupIn(WriteQueue.class, MethodHandles.lookup()).findVarHandle(WriteQueue.class, "channel", Channel.class);
        } catch (NoSuchFieldException | IllegalAccessException e) {
            throw new RuntimeException(e);
        }
    }

    @SneakyThrows
    public static Channel getChannel(ServerStream serverStream) {
        if (serverStream instanceof NettyServerStream nettyServerStream) {
            Object writeQueue = WRITE_QUEUE_HANDLE.get(nettyServerStream);
            return (Channel) CHANNEL_HANDLE.get(writeQueue);
        }

        return null;
    }

}
